#include "RpcConfig.h"
#include "Logger.h"

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

void RpcConfig::Trim(std::string &src)
{
    if(src.empty())
    {
        return;
    }

    src.erase(0, src.find_first_not_of(" "));
    src.erase(src.find_last_not_of(" ") + 1);
}

void RpcConfig::LoadConfigFile(const std::string &configfile)
{
    // std::cout << "RpcConfig::LoadConfigFile()" << std::endl;
    LOG_INFO("RpcConfig::LoadConfigFile()");

    // 将配置文件全部读入内存
    std::ifstream f_in(configfile);
    if(!f_in)
    {
        // std::cout << "open configfile failed" << std::endl;
        LOG_ERROR("open configfile failed");
        exit(EXIT_FAILURE);
    }
    std::string config((std::istreambuf_iterator<char>(f_in)), std::istreambuf_iterator<char>());


    // 逐行读取配置文件
    std::string line;
    std::istringstream s_in(config);
    while(std::getline(s_in, line))
    {
        // 跳过空行
        if (line.empty())
        {
            continue;
        }

        // 去除行头尾空格
        Trim(line);

        // 跳过行头注释
        if (line[0] == '#')
        {
            continue;
        }

        // 删除行尾注释
        size_t pos = line.find('#');
        if (pos != std::string::npos)
        {
            line.erase(pos);
        }

        // 解析配置项，通过'='分割
        std::string key;
        std::string value;
        pos = line.find('=');
        if (pos == std::string::npos)
        {
            continue;
        }
        key = line.substr(0, pos);
        Trim(key);
        value = line.substr(pos + 1);
        Trim(value);

        // 插入到map中
        m_configMap[key] = value;
    }
}

std::string RpcConfig::GetConfig(const std::string &key)
{
    // std::cout << "GetConfig()" << std::endl;
    LOG_INFO("GetConfig()");

    if(m_configMap.find(key) == m_configMap.end())
    {
        return "";
    } else {
        return m_configMap[key];
    }
}

void RpcConfig::PrintConfig()
{
    // std::cout << "RpcConfig::PrintConfig()" << std::endl;
    LOG_INFO("RpcConfig::PrintConfig()");

    for(auto &item : m_configMap)
    {
        // std::cout << item.first << " : " << item.second << std::endl;
        LOG_INFO("%s : %s", item.first.c_str(), item.second.c_str());
    }
}